﻿/////////////////////////////////////////////
/// Author:     Anders K. Jacobsen
/// E-Mail:     anders@pings.dk
/// Date:       24. Mar 2008
/// /////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint;
using AKJ.Sharepoint.Branding.Config;
using AKJ.Sharepoint.Branding.BrandingInterceptor;
using System.Reflection;
using System.Collections;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using AKJ.Sharepoint.Branding.Code;
using Microsoft.SharePoint.Administration;

namespace AKJ.Sharepoint.Branding.HTTPModules
{
    class SharepointBrandingModule_old : IHttpModule
    {
        public SharepointBrandingModule_old()
        { }

        #region IHttpModule Members
        public void Dispose()
        { }

        public void Init(HttpApplication context)
        {
            // Hook into preRequestHandler
            context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
        }

        /// <summary>
        /// In the PreRequestHandlerExecute we change the master page for PublishingPages.
        /// For "normal" WSS 3.0 pags we let the PreInit Handler do the job.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void context_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            if (HttpContext.Current == null)
                return;

            Page page = HttpContext.Current.CurrentHandler as Page;

            if (page != null)
            {
                page.PreInit += new EventHandler(page_PreInit);
            }
        }

        /// <summary>
        /// First event where the Request instance is initialized
        /// (and before the Control structure is build so MasterPage
        /// can still be changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void page_PreInit(object sender, EventArgs e)
        {
            Page page = sender as Page;

            if (page == null)
                return;

            RebuildRebrandingIndex(page);

            // Now perform the 
            ProcessBrandings(page);
        }

        /// <summary>
        /// Rebuild the Branding Index
        /// </summary>
        /// <param name="page"></param>
        private void RebuildRebrandingIndex(Page page)
        {
            //if (BrandingManager.IsPathBranded(HttpContext.Current.Request.RawUrl) == false)
            {
                SortedDictionary<int, IBrandingInterceptor> inspectors = GetBrandingInterceptors();

                foreach (int key in inspectors.Keys)
                {
                    IBrandingInterceptor inspector = inspectors[key];
                    inspector.InterceptRequest(page,null);
                }

                //BrandingManager.MarkPathAsInitialized(HttpContext.Current.Request.RawUrl);
            }
        }

        /// <summary>
        /// Parse request via branding modules
        /// </summary>
        /// <param name="page"></param>
        private void ProcessBrandings(Page page)
        {
            BrandingPair master = BrandingManager_old.GetCurrentBrandingElement(BrandingElementType.AKJ_Sharepoint_Master, HttpContext.Current.Request.RawUrl);
            BrandingPair css = BrandingManager_old.GetCurrentBrandingElement(BrandingElementType.AKJ_Sharepoint_Css, HttpContext.Current.Request.RawUrl);

            // Should master be rebranded?
            if (master != null && master.Element != "")
            {
                RebrandMaster(page, master);
            }

            // Should css be rebranded?
            if (css != null && css.Element != "")
            {
                //Delegate rebranding to PreRender
                page.PreRender += new EventHandler(page_PreRender);
            }
        }

        /// <summary>
        /// Perform CSS rebrandig
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void page_PreRender(object sender, EventArgs e)
        {
            Page page = sender as Page;
            BrandingPair css = BrandingManager_old.GetCurrentBrandingElement(BrandingElementType.AKJ_Sharepoint_Css, HttpContext.Current.Request.RawUrl);

            if (page != null && css != null)
            {
                RebrandCSS(page, css);
            }

            SPContext.Current.Web.AllowUnsafeUpdates = false;
        }

        private void RebrandMaster(Page page, BrandingPair applyMasterElement)
        {
            // If the request originates from a Publishing Page then we have to
            // change the master page on the current Sharepoint Web instance object
            // (of course we don't want to persist this change since it would
            // change the master page permanently..for all users).
            if (page is PublishingLayoutPage || page is TemplateRedirectionPage)
            {
                SPContext.Current.Web.AllowUnsafeUpdates = true;

                //web.Site.AllowUnsafeUpdates = true;
                SPContext.Current.Web.CustomMasterUrl = applyMasterElement.Element;
            }
            else
            {
                // Now, if this is a normal wss 3.0 page hook into
                // the PreInit event (just before the ordinary Page event
                // cycle starts.                                
                page.MasterPageFile = applyMasterElement.Element;
            }
        }

        private void RebrandCSS(Page page, BrandingPair applyCssElement)
        {
            HtmlLink csslink = new HtmlLink();
            csslink.Href = applyCssElement.Element;
            csslink.Attributes["text"] = "text/css";
            csslink.Attributes["rel"] = "stylesheet";

            if (page.Header != null)
                page.Header.Controls.AddAt(page.Header.Controls.Count, csslink);
            else
                if (SPContext.Current != null && SPContext.Current.Web != null)
                {
                    SPWeb web = SPContext.Current.Web;
                    web.AllowUnsafeUpdates = true;
                    web.Site.AllowUnsafeUpdates = true;

                    web.AlternateCssUrl = applyCssElement.Element;
                }
        }

        #endregion

        /// <summary>
        /// Load and return interceptors modules
        /// </summary>
        /// <returns></returns>
        private SortedDictionary<int, IBrandingInterceptor> GetBrandingInterceptors()
        {
            VisualBrandingSection config = VisualBrandingSection.Instance();

            SortedDictionary<int, IBrandingInterceptor> interceptors = new SortedDictionary<int, IBrandingInterceptor>();

            // Fetch and Unwrap Interceptors
            // TODO: Perform some caching of already loaded insectors to reduce reflection/instantiation.
            foreach (BrandingInterceptorElement interceptor in config.BrandingInterceptors)
            {
                IBrandingInterceptor i = AppDomain.CurrentDomain.CreateInstanceAndUnwrap(interceptor.Assembly, interceptor.Type) as IBrandingInterceptor;

                if (i != null)
                    interceptors.Add(int.Parse(interceptor.Priority), i);
            }

            return interceptors;
        }
    }
}